  /*
  *
  * This function will create an ajax object, regardless of which client is
  * used
  *
  * If the creation fails, an alert window will be issued
  *
  */

  function createAjaxObject() {
    var AJAXObj;

    try {
      // FIrefox, Opera 8.0+, Safari
      AJAXObj = new XMLHttpRequest();

      //if (http_request.overrideMimeType) {
      //  // set type accordingly to anticipated content type
      //  http_request.overrideMimeType('text/html');
      //}
    } catch (e) {
      //Internet Explorer
      try {
        AJAXObj = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          AJAXObj = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
          alert('Your browser does not support AJAX. Please upgrade your browser');
          return false;
        }
      }
    }

    return AJAXObj;
  }

  /*
  *
  * This function is called when a factoid is deleted, or undeleted
  *
  * The id represents the row to update
  *
  */

  function alterFactoidState(id) {
    var AJAXObj;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to change the item visibility. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText == "1" && getItem('visibility'+id)) {
            // The request failed. Revert the status
            switchVisibility('visibility' + id,'active','deleted');
          } else if (AJAXObj.responseText == "0" && getItem('visibility'+id)) {
            switchVisibility('visibility' + id,'deleted','active');

            var className = getItem('visibility' + id).className;

            if (className == "" || className == "null") {
              className = getItem('visibility' + id).getAttribute('class');
            }

            if (className == "" || className == "null") {
              className = getItem('visibility' + id).getAttribute('className');
            }

            if (className == 'deleted') {
              changeClass('lock' + id, 'locked');
              changeClass('value' + id, 'disabled_field');
              getItem('value' + id).value = '<reply>';
            }
          }
        }
      }
    }

    if (getItem('visibility' + id)) {
      var className = getItem('visibility' + id).className;

      if (className == "" || className == "null") {
        className = getItem('visibility' + id).getAttribute('class');
      }

      if (className == "" || className == "null") {
        className = getItem('visibility' + id).getAttribute('className');
      }

      if (className == 'deleted') {
        // The user wants to re-activate the factoid
        var parameters = "action=activate&id=" + id + "&sourceKey=" + getItem('key'+id).value;
        AJAXObj.open("POST","process.php",true);

        AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        AJAXObj.setRequestHeader("Content-length", parameters.length);
        AJAXObj.setRequestHeader("Connection", "close");
        // Send the AJAX request
        AJAXObj.send(parameters);
      } else if (className == 'active') {
        // The user wants to delete the factoid
        var parameters = "action=delete&id=" + id + "&sourceKey=" + getItem('key'+id).value;
        AJAXObj.open("POST","process.php",true);

        AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        AJAXObj.setRequestHeader("Content-length", parameters.length);
        AJAXObj.setRequestHeader("Connection", "close");
        // Send the AJAX request
        AJAXObj.send(parameters);
      }
    }
  }

  function updateFactoidValue(id) {
    var AJAXObj;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to update the factoid value. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText.length >= 2 && AJAXObj.responseText.substring(0, 2) == "1:" && getItem('value'+id)) {
            // The request failed. Revert the text from the db
            getItem('value'+id).value = AJAXObj.responseText.substring(2);
          } else if (AJAXObj.responseText.length >= 2 && AJAXObj.responseText.substring(0, 2) == "0:" && getItem('value'+id)) {
            changeClass('value'+id, "edited_field");
          }
        }
      }
    }

    if (getItem('key'+id) && getItem('value'+id)) {
      var sourceKey = getItem('key'+id).value;
      var factoidValue = getItem('value'+id).value;

      sourceKey = sourceKey.replace(/#/,'%23',sourceKey);
      sourceKey = sourceKey.replace(/\?/,'%3F',sourceKey);

      factoidValue = factoidValue.replace(/#/,'%23',factoidValue);
      factoidValue = factoidValue.replace(/\?/,'%3F',factoidValue);

      var parameters = "action=update&id=" + id + "&sourceKey=" + sourceKey + "&factoidValue=" + factoidValue;
      AJAXObj.open("POST","process.php",true);

      AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      AJAXObj.setRequestHeader("Content-length", parameters.length);
      AJAXObj.setRequestHeader("Connection", "close");
      // In this case, an UPDATE is always performed
      // Send the AJAX request
      AJAXObj.send(parameters);
    }
  }

  function recoverFactoidValue(id) {
    var AJAXObj;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to update the factoid value. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText.length >= 2 && AJAXObj.responseText.substring(0, 2) == "0:" && getItem('value'+id)) {
            if (getItem('value'+id).value != AJAXObj.responseText.substring(2)) {
              changeClass('value'+id, "edited_field");
              getItem('value'+id).value = AJAXObj.responseText.substring(2);
            }
          }
        }
      }
    }

    if (getItem('key'+id) && getItem('value'+id)) {
      var sourceKey = getItem('key'+id).value;
      var factoidValue = getItem('value'+id).value;

      sourceKey = sourceKey.replace(/#/,'%23',sourceKey);
      sourceKey = sourceKey.replace(/\?/,'%3F',sourceKey);

      factoidValue = factoidValue.replace(/#/,'%23',factoidValue);
      factoidValue = factoidValue.replace(/\?/,'%3F',factoidValue);

      var parameters = "action=recover&id=" + id + "&sourceKey=" + sourceKey + "&factoidValue=" + factoidValue;
      AJAXObj.open("POST","process.php",true);

      AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      AJAXObj.setRequestHeader("Content-length", parameters.length);
      AJAXObj.setRequestHeader("Connection", "close");
      // In this case, an UPDATE is always performed
      // Send the AJAX request
      AJAXObj.send(parameters);
    }
  }

  function lockUnlockFactoid(id) {
    var AJAXObj;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to lock or unlock the factoid. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText == "1" && getItem('lock'+id)) {
            // The request failed. Revert the status
            switchVisibility('lock' + id,'locked','unlocked');
          } else if ((AJAXObj.responseText == "2" || AJAXObj.responseText == "3") && getItem('lock'+id)) {
            switchVisibility('lock' + id,'locked','unlocked');

            if (getItem('value'+id)) {
              switchVisibility('value' + id,'form_element','disabled_field');
            }
          }
        }
      }
    }

    if (getItem('lock' + id)) {
      var className = getItem('lock' + id).className;

      if (className == "" || className == "null") {
        className = getItem('lock' + id).getAttribute('class');
      }

      if (className == "" || className == "null") {
        className = getItem('lock' + id).getAttribute('className');
      }

      if (className == 'unlocked') {
        // The user wants to re-activate the factoid
        var parameters = "action=lock&id=" + id + "&sourceKey=" + getItem('key'+id).value;
        AJAXObj.open("POST","process.php",true);

        AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        AJAXObj.setRequestHeader("Content-length", parameters.length);
        AJAXObj.setRequestHeader("Connection", "close");
        // Send the AJAX request
        AJAXObj.send(parameters);
      } else if (className == 'locked') {
        // The user wants to delete the factoid
        var parameters = "action=unlock&id=" + id + "&sourceKey=" + getItem('key'+id).value;
        AJAXObj.open("POST","process.php",true);

        AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        AJAXObj.setRequestHeader("Content-length", parameters.length);
        AJAXObj.setRequestHeader("Connection", "close");
        // Send the AJAX request
        AJAXObj.send(parameters);
      }
    }
  }

  /*
  *
  * Generic function to get an element on the page from the id
  *
  * Compatible with all browsers
  *
  */

  function getItem(id, context) {
    var itm = false;

    if (context == 'parent' && parent.document.getElementById) {
      itm = parent.document.getElementById(id);
    } else if (document.getElementById) {
      itm = document.getElementById(id);
    } else if (document.all) {
      itm = document.all[id];
    } else if (document.layers) {
      itm = document.layers[id];
    }

    return itm;
  }

  /*
   *
   * Change the class of an item, dynamically
   *
   * Used for rollover effects
   *
   */

  function changeClass(item, className) {
    // Non-IE
    getItem(item).removeAttribute("class");
    // IE
    getItem(item).removeAttribute("className");
    // Non-IE
    getItem(item).setAttribute("class", className);
    // IE
    getItem(item).setAttribute("className", className);
  }

  /*
   *
   * Change the class of an item, dynamically
   *
   * Used to change the visibility icon back and forth
   *
   * Note: this class might be reverted if the AJAX function returns 1
   *
   */

  function switchVisibility(itemName, strStatus1, strStatus2) {
    if (getItem(itemName)) {
      // This should work most of the time
      var className = getItem(itemName).className;

      if (className == "" || className == "null") {
        // It failed. Try something else
        // Non-IE
        className = getItem(itemName).getAttribute('class');
      }

      if (className == "" || className == "null") {
        // It failed. Try something else
        // IE
        className = getItem(itemName).getAttribute('className');
      }

      if (className == strStatus1) {
        changeClass(itemName, strStatus2);
      } else if (className == strStatus2) {
        changeClass(itemName, strStatus1);
      }
    }
  }

  /*
   *
   * Navigate to a specific page, knowing the current number of pages
   *
   */

  function gotopage(intOffset, intMax) {
    // Navigate to another page using an offset, and respecting the upper limit
    if (getItem('currentpage').value == "") {
      getItem('currentpage').value = "1";
    }

    getItem('currentpage').value = (getItem('currentpage').value * 1) + (intOffset * 1);

    if (getItem('currentpage').value <= 0) {
      getItem('currentpage').value = 1;
    } else if (getItem('currentpage').value > intMax) {
      getItem('currentpage').value = intMax;
    }

    document.factoids.submit();
  }

  function changeSortingOrder(strClickedColumnName) {
    if (getItem('orderby_column') && getItem('orderby_order')) {
      if (getItem('orderby_column').value == strClickedColumnName) {
        if (getItem('orderby_order').value == 'asc') {
          getItem('orderby_order').value = 'desc';
        } else {
          getItem('orderby_order').value = 'asc';
        }
      } else {
        getItem('orderby_column').value = strClickedColumnName;
        getItem('orderby_order').value = 'asc';
      }
    }
  }

  function deleteRestoreAllFactoids(strAction) {
    var AJAXObj;
    var index1;
    var returnValue, returnedID;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to change the items visibility. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText.length > 0) {
            index1 = AJAXObj.responseText.indexOf(':');

            if (index1 > 0) {
              returnValue = AJAXObj.responseText.substring(0, index1);
              returnedID = AJAXObj.responseText.substring(index1+1);

              var returnArray = returnedID.split(',');
              var returnArraySize = returnArray.length;

              if (returnValue == "0" || returnValue == "2") {
                for (var j = 0; j < returnArraySize; j++) {
                  if (getItem('exclude' + returnArray[j]) && !getItem('exclude' + returnArray[j]).checked) {
                    if (strAction == "batchdelete" && getItem('visibility'+returnArray[j])) {
                      changeClass('visibility' + returnArray[j], 'deleted');
                      changeClass('lock' + returnArray[j], 'locked');
                      changeClass('value' + returnArray[j], 'disabled_field');
                      getItem('value' + returnArray[j]).value = '<reply>';
                    } else if (strAction == "batchactivate" && getItem('visibility'+returnArray[j])) {
                      changeClass('visibility' + returnArray[j], 'active');
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    var strResponse = "";

    if (strAction == "batchdelete") {
      strResponse = "This option will delete all visible factoids, preventing fajita from responding to them in the channels. " +
                    "Deleting a factoid also locks it and sets the response to '<reply>' automatically.\n\n" +
                    "Factoids may be excluded with the left-most column.\n\n" +
                    "Are you sure you want to proceed?";
    } else if (strAction == "batchactivate") {
      strResponse = "This option will restore all visible factoids, allowing fajita to respond to them in the channels.\n\n" +
                    "Factoids may be excluded with the left-most column.\n\n" +
                    "Are you sure you want to proceed?";
    }

    if (window.confirm(strResponse)) {
      var batchIDs = "";

      for (var id = 0; id < 10; id++) {
        if (getItem('id' + id)) {
          if (batchIDs == "") {
            batchIDs = getItem('id'+id).value;
          } else {
            batchIDs = batchIDs + "," + getItem('id'+id).value;
          }
        }
      }

      var parameters = "action=" + strAction + "&id=" + batchIDs + "&sourceKey=";
      AJAXObj.open("POST","process.php",true);

      AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      AJAXObj.setRequestHeader("Content-length", parameters.length);
      AJAXObj.setRequestHeader("Connection", "close");
      // Send the AJAX request
      AJAXObj.send(parameters);
    }
  }

  function lockUnlockAllFactoids(strAction) {
    var AJAXObj;
    var index1;
    var returnValue, returnedID;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to lock or unlock the factoids. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText.length > 0) {
            index1 = AJAXObj.responseText.indexOf(':');

            if (index1 > 0) {
              returnValue = AJAXObj.responseText.substring(0, index1);
              returnedID = AJAXObj.responseText.substring(index1+1);

              var returnArray = returnedID.split(',');
              var returnArraySize = returnArray.length;

              if (returnValue == "0" || returnValue == "2") {
                for (var j = 0; j < returnArraySize; j++) {
                  if (getItem('exclude' + returnArray[j]) && !getItem('exclude' + returnArray[j]).checked) {
                    if (strAction == "batchlock" && getItem('lock'+returnArray[j])) {
                      changeClass('lock' + returnArray[j], 'locked');
                      changeClass('value' + returnArray[j], 'disabled_field');
                    } else if (strAction == "batchunlock" && getItem('lock'+returnArray[j])) {
                      changeClass('lock' + returnArray[j], 'unlocked');
                      changeClass('value' + returnArray[j], 'form_element');
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    var strResponse = "";

    if (strAction == "batchlock") {
      strResponse = "This option will lock all visible factoids, preventing their value from being modified in the channels.\n\n" +
                    "Factoids may be excluded with the left-most column.\n\n" +
                    "Are you sure you want to proceed?";
    } else if (strAction == "batchunlock") {
      strResponse = "This option will unlock all visible factoids, allowing their value to be modified in the channels.\n\n" +
                    "Factoids may be excluded with the left-most column.\n\n" +
                    "Are you sure you want to proceed?";
    }

    if (window.confirm(strResponse)) {
      var batchIDs = "";

      for (var id = 0; id < 10; id++) {
        if (getItem('id' + id)) {
          if (batchIDs == "") {
            batchIDs = getItem('id'+id).value;
          } else {
            batchIDs = batchIDs + "," + getItem('id'+id).value;
          }
        }
      }

      var parameters = "action=" + strAction + "&id=" + batchIDs + "&sourceKey=";
      AJAXObj.open("POST","process.php",true);

      AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      AJAXObj.setRequestHeader("Content-length", parameters.length);
      AJAXObj.setRequestHeader("Connection", "close");
      // Send the AJAX request
      AJAXObj.send(parameters);
    }
  }

  function eraseRestoreAllFactoids(strAction) {
    var AJAXObj;
    var index1;
    var returnValue, returnedID;

    // Create the AJAX object
    AJAXObj = createAjaxObject();

    if (AJAXObj == false) {
      return false;
    }

    AJAXObj.onreadystatechange = function() {
      if (AJAXObj.readyState == 4) {
        if (AJAXObj.status != 200) {
          alert('Unable to lock or unlock the factoids. Please refresh the page, and try again.');
        } else {
          // The request has completed
          if (AJAXObj.responseText.length > 0) {
            index1 = AJAXObj.responseText.indexOf(':');

            if (index1 > 0) {
              returnValue = AJAXObj.responseText.substring(0, index1);
              returnedID = AJAXObj.responseText.substring(index1+1);

              var returnArray = returnedID.split(',');
              var returnArraySize = returnArray.length;

              if (returnValue == "0" || returnValue == "2") {
                for (var j = 0; j < returnArraySize; j++) {
                  if (getItem('exclude' + returnArray[j]) && !getItem('exclude' + returnArray[j]).checked) {
                    if (strAction == "batcherase" && getItem('value'+returnArray[j])) {
                      getItem('value' + returnArray[j]).value = '<reply>';
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    if (window.confirm("This option will set all the visible factoids to '<reply>', preventing fajita from responding to them in the channels.\n\n" +
                       "Factoids may be excluded with the left-most column.\n\n" +
                       "Are you sure you want to proceed?")) {
      var batchIDs = "";

      for (var id = 0; id < 10; id++) {
        if (getItem('id' + id)) {
          if (batchIDs == "") {
            batchIDs = getItem('id'+id).value;
          } else {
            batchIDs = batchIDs + "," + getItem('id'+id).value;
          }
        }
      }

      var parameters = "action=" + strAction + "&id=" + batchIDs + "&sourceKey=";
      AJAXObj.open("POST","process.php",true);

      AJAXObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      AJAXObj.setRequestHeader("Content-length", parameters.length);
      AJAXObj.setRequestHeader("Connection", "close");
      // Send the AJAX request
      AJAXObj.send(parameters);
    }
  }
